<script setup lang="ts">
import topTable from './components/top-table.vue';
import { message } from '@/components/q-message/message';
import { searchConfig } from './config/search-config';
import { tableConfig } from './config/table-config';
import { generateNameToLevel } from '@/config/constant';
import { difference } from 'lodash-es';
import { initTopTableData } from '@/views/Base/WorkCalendar/common';
import {
    doGetEquipmentList,
    doGetClassSystemDetail,
    doUpdateClassSystem
} from '@/api/base/workCalendar/shiftSystem/index.ts';
import type {
    ClassSystem,
    WorkingDayPeriods,
    EquipmentCollection,
    UpdateClassSystemData
} from '@/api/base/workCalendar/shiftSystem/model/type';

const emit = defineEmits(['getData']);

// top-table 表格数据
const topTableData = ref<WorkingDayPeriods[]>(initTopTableData());

// 下方表格选中的id
const equipmentIds = ref<number[]>([]);

// 表格ref
const topTableRef = ref<InstanceType<typeof topTable>>();

// 工作时段勾选的id
const workingDays = computed(() => topTableRef.value?.workingDays);

const { getMaxHeight, modalSlotRef, modalOk, visible, handleCancel, loading } = useModal({
    data: { topTableData, equipmentIds, workingDays }
});

/**
 * @: 打开弹框
 */
const title = ref('编辑');
let updateId = ref<number | null>(); // 更新的id
let equipmentCollectionIds: number[] = [];
const isCheck = ref<undefined | boolean>(); // 查看
const open = (row?: ClassSystem, check?: boolean) => {
    isCheck.value = check;
    topTableData.value = initTopTableData();
    equipmentIds.value = [];
    equipmentCollectionIds = [];
    preIds.value = [];
    delIds.value = [];
    isError.value = false;
    if (row) {
        title.value = check ? '查看' : '编辑';
        updateId.value = row.id;
        equipmentCollectionIds = row.equipmentCollection?.map(item => item.id);
        getTopTableData(row.id);
        visible.value = true;
    }
};

/**
 * @: 获取top-table数据
 */
const getTopTableData = async (id: number) => {
    try {
        const { data } = await doGetClassSystemDetail({ id });
        if (data) {
            topTableData.value = data.workingDayPeriods;
        }
    } catch (error) {
        topTableData.value = initTopTableData();
    }
};

/**
 * @: 更新top-table数据
 */
const updateTopTableData = (periodDesc: string, id: number, rowWorkingDay: number[]) => {
    topTableData.value = topTableData.value.map(item => {
        if (rowWorkingDay.includes(item.workingDay)) {
            return {
                ...item,
                periodId: id,
                periodDesc
            };
        }
        return item;
    });
};

// 上一次的id
const preIds = ref<number[]>([]);
// 需要删除的id
const delIds = ref<number[]>([]);

// 选中
const selection = (row: EquipmentCollection[]) => {
    isError.value = false;
    const ids = row.map(item => item.id);
    if (preIds.value.length) {
        // 对比id筛选出取消的id
        const arr = difference(preIds.value, ids);
        if (arr) {
            delIds.value.push(...arr);
        }
    }
    equipmentIds.value = ids;
    preIds.value = ids;
};

const isError = ref(false);

/**
 * @: 提交
 */
const handleSubmit = async () => {
    const arr = [...new Set(delIds.value)]; // 去重
    const ids = difference(equipmentCollectionIds, arr);
    const allIds = [...new Set([...ids, ...equipmentIds.value])];

    if (allIds.length === 0) {
        isError.value = true;
        message.error(`请至少选择一个工作设备！`);
        return;
    }
    const checkData = topTableRef.value?.workingDays;
    let valid = false;

    // 把没有选中的过滤掉不传递给后端
    const paramsData = topTableData.value.map(item => {
        if (checkData?.includes(item.workingDay)) {
            if (!item?.periodDesc && !valid) {
                valid = true;
            }
            return item;
        }
        return {
            workingDay: item.workingDay,
            periodId: 0,
            periodDesc: ''
        };
    });

    if (valid) {
        message.error(`选中后必须选择工作时段！`);
        return;
    }

    //至少选择一个工作时段 ， 全部为零说明没有选择工作时段
    const empty = paramsData.every(item => item.periodId === 0);
    if (empty) {
        message.error(`请至少选择一个工作时段！`);
        return;
    }

    const updateData: UpdateClassSystemData = {
        workingDayPeriods: paramsData,
        equipmentIds: allIds
    };

    try {
        if (updateId.value) {
            updateData.id = updateId.value;
            const res = await doUpdateClassSystem(updateData);
            emit('getData');
            return res;
        }
    } catch (error) {
        console.log('error');
    }
};

watch(
    () => modalSlotRef.value?.tableData,
    (newData: EquipmentCollection[]) => {
        newData?.forEach(item => {
            if (item.selected) {
                if ([...new Set(delIds.value)].includes(item.id)) return;
                modalSlotRef.value.toggleRowSelection(item, true);
            }
        });
    }
);

// 工作设备列表禁用
const disabledFn = (row: EquipmentCollection) => !(isCheck.value || row.bound);

// 去新增
const router = useRouter();
const toLink = () => {
    visible.value = false;
    router.push('/equipment');
};

defineExpose({
    open
});
</script>

<template>
    <q-modal
        v-model:visible="visible"
        :title="title"
        width="900px"
        bodyHeight="520px"
        :close-cancel="true"
        :footer="!isCheck"
        centered
        :confirm-loading="loading"
        @cancel="handleCancel"
        @ok="() => modalOk(handleSubmit)"
    >
        <top-table
            ref="topTableRef"
            :tableData="topTableData"
            :isEdit="title === '编辑'"
            :isCheck="isCheck"
            @update="updateTopTableData"
        />

        <!-- 工作设备 -->
        <div class="m-t-32 m-b-24">
            工作设备列表 <span class="danger">*</span>
            <Transition name="form-error">
                <span v-show="isError" class="danger m-l-16 f14">请至少选择一个工作设备！</span>
            </Transition>
        </div>

        <!-- 搜索 -->
        <base-search
            :table-ref="modalSlotRef"
            :search-config="searchConfig"
            :close-min-width="true"
        >
            <q-push-button :is-text="false" :disabled="isCheck" @click="toLink" />
        </base-search>

        <base-table
            :id="generateNameToLevel('1')"
            ref="modalSlotRef"
            :get-data-fn="doGetEquipmentList"
            :max-height="getMaxHeight"
            :added-params="{ id: updateId }"
            :modal-mode="true"
            :show-setting="false"
            :table-config="tableConfig"
            :selectable="disabledFn"
            :un-action="true"
            @selection-change="selection"
        >
        </base-table>
    </q-modal>
</template>

<style scoped lang="scss">
@include b(danger) {
    color: #f00;
}

.form-error-enter-from,
.form-error-leave-to {
    opacity: 0;
}

.form-error-enter-active,
.form-error-leave-active {
    transition: opacity 0.3s;
}
</style>
